﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

///////////////////
//2010/01/18
//the interfaces that is used in JtextEpicsServer and JEDriver
//Driver now implement this interface to let the JEServer to call it
//the EJserver implement these interface to let other plugins toget and modify its data
////////////////////////////////////////////////




namespace JtextEpicsInterface
{
    /// <summary>
    /// If you want to Flush a record then regist this delegate to
    /// OnFlash event of the driver ,then when the driver raise this event the record will get flushed
    /// <para>normally you will not use this ,this is automaticlly done by the record</para>
    /// </summary>
    public delegate void FlushRecordHandler();  //the record is pasive flush



    /// <summary>
    /// <para>The Interface for JtextEpics record driver</para>
    /// <para>All JtextEpics Drivers should implement this Interface,then can it be load as a driver</para>
    /// <para>when you write a driver,take extra care about threading.course the record ,if is set it's own scan interval,it can call the driver function at the same time 
    /// so,maybe some conflict over driver resource,make sure you handle this.</para>
    /// </summary>
    public interface IJEDriver  //record will call this to get value from hard or  set to  hard
    {
        /// <summary>
        /// Gets the name of the driver.It's read only,and set the name in a const,hardcode
        /// </summary>
        /// <value>
        /// The name of the driver.
        /// </value>
        string DriverName { get; }  //the driver name ,JES will get this to see if this is the right driver

        /// <summary>
        /// Gets the val.
        /// <para >use the info that in the Record Property to get responding value from the hardware,
        /// this is for input record</para>
        /// </summary>
        /// <param name="DesRecord">The record property,may contain the channel info....<seealso cref="Record_prop"/></param>
        /// <returns>of course the value from the hardware</returns>
        object GetVal(Record_prop DesRecord);   //for input pvs

        /// <summary>
        /// Sets the val.
        /// <para>use the info that in the Record Property to set responding value from record to the hardware,
        /// this is for output record</para>
        /// </summary>
        /// <param name="DesRecord">The record property,may contain the channel info....<seealso cref="Record_prop"/></param>
        /// <param name="value">not used</param>
        /// <returns></returns>
        object SetVal(Record_prop DesRecord,object value);  //for output pvs

        /// <summary>
        /// Initialize the whole hardware.
        /// <para>This is called right before the start of the server,it will initialize the hardware of this Driver.</para>
        /// <para >Notice!!The IniPara is not used ,if you need parameters to config your hardware-which is the most case-,use a config file the follows your Driver dll.</para>
        /// <para>Make sure you throw a exception when noe successful</para>
        /// </summary>
        /// <param name="IniPara">Sorry not used</param>
        /// <returns>0 ok,-1 error</returns>
        bool IniHard(Record_prop IniPara); //initialize the whole hardware


        /// <summary>
        /// Initialize the channel.
        /// <para>Initialize a single channel for a singgle record ,the info is carried along with the DesRecord a record_prop</para>
        ///<para>This is called every single time when a record is initialized</para>
        ///<para>Make sure you throw a exception when noe successful</para>
        /// </summary>
        /// <param name="DesRecord">The record property,may contain the channel info....<seealso cref="Record_prop"/></param>
        /// <returns>true for ok,false for error</returns>
        bool IniChannel(Record_prop DesRecord);  //initialize some part of the hardware

        /// <summary>
        /// Starts the driver.after you have initialized everything.
        ///   then you can start records .
        /// </summary>
        /// <param name="DesRecord">The DES record.Usually Not used</param>
        /// <returns></returns>
        bool StartDriver(Record_prop DesRecord);

        /// <summary>
        /// Kills the channel.The oppsite of iniChannel
        /// </summary>
        /// <param name="DesRecord">The record property,may contain the channel info....<seealso cref="Record_prop"/></param>
        void KillChannel(Record_prop DesRecord);    //kill a channel not usually needed
        
        /// <summary>
        /// Kills the hardware.The oppsite of IniHard
        /// </summary>
        /// <param name="DesRecord">Not used</param>
        void KillHard(Record_prop DesRecord);    //kill a the whole driver

        /// <summary>
        /// Occurs when [on flush].
        /// <para>When the record is set to Passive scan, it will not flush itself,untill the driverr tell it to.so Rais this Event ,when you1need the record flushes</para>
        /// </summary>
        event FlushRecordHandler OnFlush;   //pasive flush the record
    }


    /// <summary>
    /// <para>The inter face for the PlugIn used in JtextEpics</para>
    /// <para>All JtextEpics PlugIn must implement this interface</para>
    /// <para>plugin has very hight accessibliy,it can access a record ,of course it's past to the plugin,via the record it can
    ///  Access other record on these server youcan also start you own client to access other record out side this server,and do any thing you can imaging</para>
    /// </summary>
    public interface IJEPlugIn      //record will call this between flush and flush2 will give this the IJErecor as argument
    {
        //Record will call this in a full flush between of flush flush2 
        /// <summary>
        /// Gets the name of the plug in.
        /// <para>plaese use a const and hard code it </para>
        /// </summary>
        /// <value>
        /// The name of the plug in.read only
        /// </value>
        string PlugInName { get; }
        
        /// <summary>
        /// Initialize the plug in.
        /// <para>This is call onec at the beginning for the server start up,and the record is not going to initialize any thing later so finish all the initialize job.
        /// <para>like drvier you normally need some parameter,so use a gonfig file for this job</para>
        /// </summary>
        /// <param name="iniObject">Not used.</param>
        void IniPlugIn(object iniObject, IJERecord record);    //usually a string, sedn selfin

        /// <summary>
        /// Runs the plug in.
        /// <Para>the record will call this each time it get flushed,for input and out put there  maybe differences.Look up example if you are making plugin</Para>
        /// </summary>
        /// <param name="myRecord">My record.The record that called the plugIn,you can set get and do anything</param>
        /// <returns>if successful</returns>
        bool RunPlugIn(IJERecord myRecord);


        /// <summary>
        /// Kills the plug in when you don't need it.
        /// </summary>
        void KillPlugIn();
    }



    /// <summary>
    /// The interface of the JtextEpics Record.
    /// <para>for Plugin and things that out side the JtextEpics Server to manipulate the record</para>
    /// <para>You can get and set the record value,get the information of the record..</para>
    /// </summary>
    public interface IJERecord      //let the plugin access the data in side the record
    {
        /// <summary>
        /// Gets the name of the pv.
        /// </summary>
        /// <value>
        /// The name of the pv.
        /// </value>
        string pvName{get; }
        /// <summary>
        /// Gets or sets the VAL.
        /// <para>this val is not the pv value,it the val the is not been proceessed by Pluguin</para>
        /// <para>For output this is equals to PV value ,youcan change this to meet the hardware output</para>
        /// <para>For input if the raw value from the hardware,you can this it will be put into PV later</para>
        /// </summary>
        /// <value>
        /// The VAL.
        /// </value>
        object VAL { get; set; }    //the valB in record
        
        /// <summary>
        /// Gets or sets the PV val,not if it a input record it will override this PV value by VAL.
        /// </summary>
        /// <value>
        /// The PVAL.
        /// </value>
        object PVAL { get; set; }   //the pvs
        //void BigFlush();    //is used when pasive flush now out side the JEserver object no one is allow to flush a record,however the driver  can do this but rais event

        /// <summary>
        /// Occurs when [on my flush].
        /// <para>record itself can also trigger a event when flushed by itself the flush timer</para>
        /// </summary>
        event FlushRecordHandler OnMyFlush;   //record itself can also trigger a event when flushed by itself the flush timer

        /// <summary>
        /// Gets the record property.
        ///   Contains all informations that the record has
        ///   <seealso cref="Record_prop"/>
        /// </summary>
        Record_prop RecordProperty{get;}

        /// <summary>
        /// This is for Plug-ins to trigger the flush of the record
        /// </summary>
        void BigFlush();

        /// <summary>
        /// Gets the parent server.
        /// You can access the server by using this interface .and then access other record on this server
        /// </summary>
        IJEServer ParentServer { get; } //return the server that holds this record  ,let the plugin access theserver in order to access the other record
    }



    /// <summary>
    /// using this interface you can access recoder on this server
    /// </summary>
    public interface IJEServer  //via IJERecor plugin canaccess the server
    {
        /// <summary>
        /// Gets the <see cref="JtextEpicsInterface.IJERecord"/> with the specified pv name.
        /// </summary>
        IJERecord this[string pvName] { get;  }
        /// <summary>
        /// Occurs when [on my flush].
        /// <para>the server may flush some record at a certain interval,when flus this's raised</para>
        /// </summary>
        event FlushRecordHandler OnMyFlush;   //when server flush the record this event is raised

        /// <summary>
        /// Gets or sets the device tbale.This table is mostly like been used by plugin
        /// </summary>
        /// <value>
        /// The device tbale.
        /// </value>
        Hashtable DeviceTable { get; set; }

    }







   

   

}
